﻿#pragma once

#include "Misc/CommonMacros.h"
#include "TextArrangeParameters.h"
#include "Font/CharTexture.h"

struct SFreeTypeGlyph;
class RTexture2D;

struct WHENGINE_API SLineRenderInfo
{
    //行的内容在字符串中的起始和结束位置 [StartCharIndex,EndCharIndex]
    int32_t StartCharIndex=-1;
    int32_t EndCharIndex=-1;

    //行的宽度
    float Width=0;

    //行在整个绘制区域中的位置
    //将行简化为一个矩形，这个矩形的上边是文字的顶线，下边是文字的底线
    float XInRenderArea=0;
    float YInRenderArea=0;
};

struct WHENGINE_API SCharRenderInfo
{
    char32_t Char;

    //是否是换行符
    bool IsNewLine=false;

    //字符占用的宽度，包含空白区域
    //字符之间视为没有空隙,比如"abc"的宽度等于'a'的宽度+'b'的宽度+'c'的宽度
    //如果是分散对齐，分散对齐带来的空白也会被计算在内
    //字符占用的高度=行高
    //这个变量用于计算光标位置
    float OcuppiedWidth=0;

    //字符在行中的偏移量，包含空白区域
    //字符在行中Y轴的偏移量为0
    //这个变量用于计算光标位置
    float OcuppiedRectMinX=0;

    //文字图片源,如果文字被剔除（不在任何行中），那么这个指针为空
    std::shared_ptr<SFreeTypeGlyph> Glyph;

    //文字图片
    //如果文字被剔除（不在任何行中），那么这个指针为空
    //如果文字是不需要渲染的特殊字符(比如' ')，那么这个指针为空
    TOptional<SCharTexture> Texture;

    //文字图片在行中的位置
    //不包含空白区域
    float TextureXInLine=0;
    float TextureYInLine=0;

    //文字图片在最终图像上的位置
    //不包含空白区域
    float OffsetXInWholeImage=0;
    float OffsetYInWholeImage=0;

};    

//文字排版结果
struct WHENGINE_API SArrangedText
{
    //排版参数
    STextArrangePapameters Parameters;

    //排版后的行信息，包含不绘制任何字符的行
    TVector<SLineRenderInfo> Lines;

    //排版后的字符信息,与字符串中的字符一一对应,不包括结尾'\0'
    TVector<SCharRenderInfo> Chars;

    //行距
    float LineHeight=0;

    //获取所有字符在绘制区域上的位置
    TVector<SVec2> GetCharPositions() const;

    //获取所有字符最终的纹理
    TVector<SRenderCharTexture> GetRenderCharTextures() const;

    // //整个文本图片的宽度和高度
    // SVec2 WholeImageSize;

    // //整个文本图片相对于绘制区域的偏移量
    // SVec2 WholeImageOffset;

    // TSharedObjectPtr<RTexture2D> WholeImage;

    //文本的大小,包含空白区域
    SVec2 CalculateTextSize()const;

    //根据输入的绘制区域位置，计算光标在哪个字符之后，如果光标在开头，返回-1
    int32_t CalculateCursorIndex(const SVec2& CursorPositionInRenderArea)const;
    
    /// @brief 计算光标在绘制区域中的位置和大小
    /// @param CursorPosition  光标在哪个字符之后，如果光标在开头，就是-1
    /// @param CursorWidth 光标本身的宽度
    /// @return 
    SRect CalculateCursorRect(int32_t CursorPosition,float CursorWidth)const;

    //获取被渲染的字符数量。
    //所谓被渲染的字符，指的是放进最后的图片中的字符，不包括被剔除的字符和不需要渲染的特殊字符
    int32_t GetRenderCharCount()const;
    bool IsCharRendered(int32_t CharIndex)const;
    //获取一个被渲染字符的图像尺寸
    SVec2 GetRenderedCharRenderSize(int32_t CharIndex) const;
    //获取一个被渲染字符在最终图像上的位置
    SVec2 GetRenderedCharPositionInImage(int32_t CharIndex)const;

};